package zack.project.domain.rebate.service;

import zack.project.domain.rebate.adapter.repository.IBehaviorRebateRepository;
import zack.project.domain.rebate.event.SendRebateMessageEvent;
import zack.project.domain.rebate.model.aggregate.BehaviorRebateAggregate;
import zack.project.domain.rebate.model.entity.BehaviorEntity;
import zack.project.domain.rebate.model.entity.BehaviorRebateOrderEntity;
import zack.project.domain.rebate.model.entity.TaskEntity;
import zack.project.domain.rebate.model.valobj.DailyBehaviorRebateVO;
import zack.project.domain.rebate.model.valobj.TaskStateVO;
import zack.project.types.common.Constants;
import zack.project.types.event.BaseEvent;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @author A1793
 */
@Service
@Slf4j
public class BehaviorRebateService implements IBehaviorRebateService {

    @Resource
    private IBehaviorRebateRepository behaviorRebateRepository;

    @Resource
    private SendRebateMessageEvent sendRebateMessageEvent;

    @Override
    public List<String> createOrder(BehaviorEntity behaviorEntity) {
        //获取所有的返利
        // id   behavior_type   rebate_desc     rebate_type  rebate_config   state
        // 1	sign	        签到返利-sku额度	sku	        9014	        open	2024-04-30 09:32:46	2024-06-22 09:52:39
        // 2	sign	        签到返利-积分	    integral	10	            open	2024-04-30 09:32:46	2024-04-30 18:05:27
        //同一个行为类型下可能会由多种返利配置，一种返利配置就对应生成一种返利单
       //根据行为实体对象的行为类型查询数据库表{daily_behavior_rebate}获取行为返利配置(行为类型，返利类型，返利值，返利描述)
        List<DailyBehaviorRebateVO> dailyBehaviorRebateVOS = behaviorRebateRepository.
                queryDailyBehaviorRebateConfig(behaviorEntity.getBehaviorTypeVO());

        if (dailyBehaviorRebateVOS == null || dailyBehaviorRebateVOS.isEmpty()) {
            return new ArrayList<>();
        }
        //根据所有行为的返利构建聚合对象,返利订单和task任务表同一事务操作
        //创建返利单的单号列表
        List<String> orderIds = new ArrayList<>();
        List<BehaviorRebateAggregate> behaviorRebateAggregates = new ArrayList<>();
        log.info("开始构建用户行为返利单 userId:{}", behaviorEntity.getUserId());
        //一种返利配置对应一个补偿任务
        for (DailyBehaviorRebateVO dailyBehaviorRebateVO : dailyBehaviorRebateVOS) {
            //用户id+返利类型+外部单号(签到日期)
            String bizId = behaviorEntity.getUserId() +
                    Constants.UNDERLINE +
                    dailyBehaviorRebateVO.getBehaviorType() +
                    Constants.UNDERLINE +
                    dailyBehaviorRebateVO.getRebateType() +
                    Constants.UNDERLINE +
                    //此处是日期或者是外部rpc调用传入的外部单号
                    behaviorEntity.getOutBusinessNo();
            //构建返利单{behavior_rebate_order}
            BehaviorRebateOrderEntity behaviorRebateOrderEntity =
                    BehaviorRebateOrderEntity.builder()
                    .userId(behaviorEntity.getUserId())
                    .orderId(RandomStringUtils.randomNumeric(12))
                    .bizId(bizId)
                    .behaviorType(dailyBehaviorRebateVO.getBehaviorType())
                    .rebateDesc(dailyBehaviorRebateVO.getRebateDesc())
                    .rebateType(dailyBehaviorRebateVO.getRebateType())
                    .rebateConfig(dailyBehaviorRebateVO.getRebateConfig())
                    .outBusinessNo(behaviorEntity.getOutBusinessNo())
                    .build();

            //构建返利消息内容
            SendRebateMessageEvent.RebateMessage rebateMessage =
                    new SendRebateMessageEvent.RebateMessage();
            rebateMessage.setUserId(behaviorEntity.getUserId());
            rebateMessage.setBizId(bizId);
            rebateMessage.setRebateType(dailyBehaviorRebateVO.getRebateType());
            rebateMessage.setRebateConfig(dailyBehaviorRebateVO.getRebateConfig());
            rebateMessage.setRebateDesc(dailyBehaviorRebateVO.getRebateDesc());
            //构建返利消息
            BaseEvent.EventMessage<SendRebateMessageEvent.RebateMessage> rebateMessageEventMessage =
                    sendRebateMessageEvent.buildEventMessage(rebateMessage);
            //构建返利补偿任务
            TaskEntity taskEntity = new TaskEntity();
            taskEntity.setUserId(behaviorEntity.getUserId());
            taskEntity.setTopic(sendRebateMessageEvent.topic());
            taskEntity.setMessageId(rebateMessageEventMessage.getId());
            taskEntity.setMessage(rebateMessageEventMessage);
            taskEntity.setState(TaskStateVO.create);
            //构建返利聚合对象，设置返利单和补偿任务
            behaviorRebateAggregates.add(BehaviorRebateAggregate.builder()
                    .userId(behaviorEntity.getUserId())
                    .taskEntity(taskEntity)
                    .behaviorRebateOrderEntity(behaviorRebateOrderEntity)
                    .build());
            orderIds.add(behaviorRebateOrderEntity.getOrderId());
        }

        //在同一事务下保存返利单实体(更新{daily_behavior_rebate})和返利补偿任务实体，
        //并向RebateMessageCustomer监听的消息队列中投放一个返利消息，RebateMessageCustomer消费消息，
        // 根据消息内容SendRebateMessageEvent.RebateMessage 的 返利类型 进行返利
        behaviorRebateRepository.saveUserRebateRecord(behaviorEntity.getUserId(), behaviorRebateAggregates);
        log.info("用户行为返利记录保存完成 userId:{}", behaviorEntity.getUserId());
        return orderIds;

    }

    @Override
    public List<BehaviorRebateOrderEntity> queryOrderByOutBusinessNo(String userId, String outBusinessNo) {
       return behaviorRebateRepository.queryOrderByOutBusinessNo(userId,outBusinessNo);
    }
}
